package com.zjuh.goodboy.index;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.zjuh.goodboy.awires.AppContextAwire;
import com.zjuh.goodboy.awires.Initializer;
import com.zjuh.goodboy.context.AppContext;
import com.zjuh.goodboy.items.Item;
import com.zjuh.goodboy.misc.DateRangeManager;
import com.zjuh.goodboy.misc.DateRangeSupport;

public class BaseIndexBuilder implements IndexBuilder, AppContextAwire, Initializer {

	protected final Logger log = LoggerFactory.getLogger(getClass());
	
	private DataProvider dataProvider;
	
	protected AppContext appContext;

	protected DocumentService documentService;
	
	private DateRangeManager dateRangeManager;
	
	public BaseIndexBuilder() {
	}
	
	public BaseIndexBuilder(DataProvider dataProvider, DocumentService documentService) {
		this.dataProvider = dataProvider;
		this.documentService = documentService;
	}

	@Override
	public void init() {
		this.documentService = (DocumentService)appContext.getObject("documentService");
		this.dateRangeManager = (DateRangeManager)appContext.getObject("dateRangeManager");
		this.dataProvider = (DataProvider)appContext.getObject(getDataProviderName());
	}
	
	protected String getDataProviderName() {
		return null;
	}

	@Override
	public void setAppContext(AppContext appContext) {
		this.appContext = appContext;
	
	}

	protected void onInit() {
		if (dataProvider instanceof DateRangeSupport) {
			((DateRangeSupport)dataProvider).setDateRange(dateRangeManager.nextDateRange());
		}
		dataProvider.init();
	}
	
	private void onDestroy() {
		dataProvider.destroy();
	}
	
	protected void onBuildBefore() {
		
	}
	
	protected void onBuildAfter() {
		
	}
	
	private void buildIndexIntern() {
		DocumentHandler documentHandler = documentService.getDocumentHandler();
		try {
			int success = 0;
			while (dataProvider.hasNext()) {
				Item item = dataProvider.next();
				if (item == null) {
					continue;
				}
				documentHandler.updateItem(item);
				++success;
			}
			documentHandler.commit();
			log.warn("success: " + success);
		} finally {
			if (documentHandler != null) {
				documentHandler.close();
			}
		}
		
	}
	
	@Override
	public void buildIndex() {
		try {
			log.warn("starting build index.");
			onInit();
			onBuildBefore();
			
			buildIndexIntern();
			
			onBuildAfter();
			log.warn("finish build index.");
		} catch (Exception e) {
			log.error("buildIndex error", e);
		} finally {
			onDestroy();
		}
		
	}

	public void setDataProvider(DataProvider dataProvider) {
		this.dataProvider = dataProvider;
	}

	public void setDocumentService(DocumentService documentService) {
		this.documentService = documentService;
	}

}
